/*
 *    Copyright 2008-2009 The PoCo Team
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package com.asemantics.poco.tests;

import java.lang.reflect.Method;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

/**
 * Defines the report of a comparison.
 *
 * @author Michele Mostarda
 * @see com.asemantics.poco.utils.BeanComparator
 * @version $Id: ComparisonReport.java 235 2009-12-19 23:26:56Z simone.tripodi@gmail.com $
 */
public class ComparisonReport {

    /**
     * Defines a single difference.
     */
    private class Difference {

        /**
         * Accessor.
         */
        private Method accessor;

        /**
         * Left value.
         */
        private Object leftValue;

        /**
         * Right value.
         */
        private Object rightValue;

        /**
         * Constructor.
         * 
         * @param acc
         * @param left
         * @param right
         */
        Difference(Method acc, Object left, Object right) {
            accessor = acc;
            leftValue = left;
            rightValue = right;
        }

        public Method getAccessor() {
            return accessor;
        }

        public Object getLeftValue() {
            return leftValue;
        }

        public Object getRightValue() {
            return rightValue;
        }

        @Override
        public String toString() {
            return String.format("Accessor: %s, left: %s, right: %s\n", accessor.getName(), leftValue, rightValue);
        }
    }

    /**
     * List of differences.
     */
    private List<Difference> differences;

    /**
     * Constructor.
     */
    protected ComparisonReport() {
        differences = new ArrayList<Difference>();
    }

    /**
     * @return list of all differences.
     */
    public List<Difference> getDifferences() {
        return Collections.unmodifiableList(differences);
    }

    /**
     * @return <code>true</code> if there is at least a difference, <code>false</code> otherwise.
     */
    public boolean isDifferent() {
        return ! differences.isEmpty();
    }

    protected void addDifference(Method accessor, Object leftValue, Object rightValue) {
        differences.add( new Difference(accessor, leftValue, rightValue) );
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        sb.append( differences.isEmpty() ? "No difference" : differences.size() + " differences." );
        sb.append("]");
        sb.append("{");
        for(Difference difference : differences) {
            sb.append( difference );
        }
        sb.append("}");
        return sb.toString();
    }

}